home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
jovept2.arc
/
WIND.C
< prev
Wrap
Text File
|
1985-05-30
|
8KB
|
426 lines
/* wind.c */
/* JOVE/MSDOS. K. Mitchum 1/85 */
/* Modifications for personal use only. */
/* original code J. Payne LSRHS 5/83 */
/* Ken Mitchum */
/* University of Pittsburgh */
/* Decision Systems Laboratory */
/* This creates/deletes/divides/grows/shrinks windows. */
#include "jove.h"
#include "term.h"
#include "screen.h"
static char onlyone[] = "You only have one window, twit!";
static char toosmall[] = "too small";
/* First line in a window */
FLine(w)
WINDOW *w;
{
WINDOW *wp = fwind;
int lineno = -1;
do {
if (wp == w)
return lineno + 1;
lineno += wp->w_height;
wp = wp->w_next;
} while (wp != fwind);
complain("WINDOW?");
/* NOTREACHED */
}
initwinds(b)
BUFFER *b;
{
WINDOW *wp = fwind;
do {
if (wp->w_bufp == b) {
SetTop(wp, (wp->w_line = b->b_dot));
zero_wind(wp);
}
wp = wp->w_next;
} while (wp != fwind);
}
/* Return last window on the screen */
WINDOW *
lastwind()
{
WINDOW *wp = fwind;
do {
if (wp->w_next == fwind)
return wp;
wp = wp->w_next;
} while (wp != fwind);
/* NOTREACHED */
}
WINDOW *
getwind()
{
WINDOW *wp;
wp = (WINDOW *)emalloc(sizeof (WINDOW));
return wp;
}
/* Delete `wp' from the screen. If it is the only window left
* on the screen, then complain via error. It gives its body
* to the next window if there is one, otherwise the previous
* window gets the body. Resets link list and fwind if necessary.
*/
del_wind(wp)
WINDOW *wp;
{
WINDOW *last = lastwind(),
*prev = wp->w_prev;
if (wp->w_next == wp)
complain(onlyone);
wp->w_prev->w_next = wp->w_next;
wp->w_next->w_prev = wp->w_prev;
if (fwind == wp) {
fwind = wp->w_next;
fwind->w_height += wp->w_height;
} else if (wp == last)
last->w_prev->w_height += wp->w_height;
else
prev->w_height += wp->w_height;
if (curwind == wp)
SetWind(prev);
free((char *) wp);
}
/* Divide the `wp'. Complains if `wp' is too small to be split.
* It returns the new window
*/
WINDOW *
div_wind(wp)
WINDOW *wp;
{
WINDOW *new;
if (wp->w_height < 4)
complain(toosmall);
new = getwind();
new->w_offset = 0;
new->w_numlines = 0;
/* Reset the window bounds */
new->w_height = (wp->w_height / 2);
wp->w_height -= new->w_height;
/* Set the lines such that w_line is the center in each window */
new->w_line = wp->w_line;
new->w_bufp = wp->w_bufp;
new->w_top = prev_line(new->w_line, HALF(new));
/* Link the new window into the list */
new->w_prev = wp;
new->w_next = wp->w_next;
new->w_next->w_prev = new;
wp->w_next = new;
return new;
}
/* Return one window previous to `wp'. If at the first window
* on screen, then go to the last window
*/
WINDOW *
prev_wind(wp)
WINDOW *wp;
{
return wp->w_prev;
}
/* Next window from `wp' */
WINDOW *
next_wind(wp)
WINDOW *wp;
{
return wp->w_next;
}
/* Initialze the first window setting the bounds to the size of the
* screen. There is no buffer with this window. See parse for the
* setting of this window.
*/
winit()
{
curwind = fwind = getwind();
curwind->w_line = curwind->w_top = (LINE *) 0;
curwind->w_char = 0;
curwind->w_next = curwind->w_prev = fwind;
curwind->w_height = LI - 1;
}
/* Change window into the previous window. curwind becomes the new
* window
*/
PrevWindow()
{
WINDOW *new = prev_wind(curwind);
if (new == curwind)
complain(onlyone);
SetWind(new);
}
/* Make new the current window */
SetWind(new)
WINDOW *new;
{
if (new == curwind)
return;
curwind->w_line = curline;
curwind->w_char = curchar;
curwind->w_bufp = curbuf;
SetBuf(new->w_bufp);
if (!inlist(new->w_bufp->b_zero, new->w_line)) {
new->w_line = curline;
new->w_char = curchar;
}
DotTo(new->w_line, new->w_char);
if (curchar > strlen(linebuf))
new->w_char = curchar = strlen(linebuf);
curwind = new;
}
/* Delete the current window if it isn't the only one left */
DelCurWindow()
{
del_wind(curwind);
}
/* Return the number of windows being displayed right now */
numwindows()
{
WINDOW *wp = fwind;
int num = 0;
do {
num++;
wp = wp->w_next;
} while (wp != fwind);
return num;
}
WindFind()
{
char *fname = ask((char *) 0, FuncName());
BUFFER *buf;
if (buf = file_exists(fname))
pop_wind(buf->b_name, 0);
else {
if (numwindows() == 1)
curwind = div_wind(curwind);
else
curwind = next_wind(curwind);
SetBuf(do_find(curwind, fname));
}
}
/* Go into one window mode by deleting all the other windows */
OneWindow()
{
while (curwind->w_next != curwind)
del_wind(curwind->w_next);
}
/* Look for a window containing a buffer whose name is `name' */
WINDOW *
windlook(name)
char *name;
{
BUFFER *bp = (BUFFER *) buf_exists(name);
WINDOW *wp = fwind;
if (bp == 0)
return 0;
do {
if (wp->w_bufp == bp)
return wp;
wp = wp->w_next;
} while (wp != fwind);
return 0;
}
/* Change window into the next window. curwind becomes the new
* window
*/
NextWindow()
{
WINDOW *new = next_wind(curwind);
if (new == curwind)
complain(onlyone);
SetWind(new);
}
/* Scroll the next window */
PageNWind()
{
if (numwindows() == 1)
complain(onlyone);
NextWindow();
NextPage();
PrevWindow();
}
/* Put a window with the buffer `name' in it. Erase the buffer if
* `clobber' is non-zero.
*/
pop_wind(name, clobber)
char *name;
{
WINDOW *wp;
BUFFER *newb;
if ((wp = windlook(name)) == 0) {
if (numwindows() == 1)
SplitWind();
else
PrevWindow();
} else
SetWind(wp);
newb = do_select((WINDOW *) 0, name);
if (clobber)
initlist(newb);
tiewind(curwind, newb);
SetBuf(newb);
}
GrowWindow()
{
WindSize(curwind, abs(exp));
}
ShrWindow()
{
WindSize(curwind, -abs(exp));
}
/* Change the size of the window by inc. First arg is the window,
* second is the increment.
*/
WindSize(w, inc)
register WINDOW *w;
{
if (numwindows() == 1)
complain(onlyone);
if (inc < 0) { /* Shrinking this window */
if (w->w_height + inc < 2)
complain(toosmall);
w->w_height += inc;
w->w_prev->w_height -= inc;
} else
WindSize(w->w_next, -inc);
}
/* Set the topline of the window, calculating its number in the buffer.
* This is for numbering the lines only.
*/
SetTop(w, line)
WINDOW *w;
register LINE *line;
{
register LINE *lp = w->w_bufp->b_zero;
register int num = 0;
w->w_top = line;
if (w->w_numlines)
while (lp) {
num++;
if (line == lp)
break;
lp = lp->l_next;
}
w->w_topnum = num;
}
WNumLines()
{
zero_wind(curwind);
/* So the redisplay will know to update the screen even if it
* looks like there are no differences.
*/
curwind->w_numlines = !curwind->w_numlines;
SetTop(curwind, curwind->w_top);
}
zero_wind(wp)
register WINDOW *wp;
{
register int i,
upper;
upper = FLine(wp);
for (i = 0; i < wp->w_height; i++)
oimage[upper + i].Line = (LINE *) -1;
}
/* Return the line number that `line' occupies in `windes' */
in_window(windes, line)
register WINDOW *windes;
register LINE *line;
{
register int i;
LINE *top = windes->w_top;
for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next)
if (top == line)
return FLine(windes) + i;
return -1;
}
/*--------------------------o.s. dependent------------------------*/
abs(i)
int i;
{
if(i >= 0) return i;
else return(-i);
}